﻿using System.Collections.Generic;
using System.IO;
using System.Xml.Linq;

namespace Maple.Weixin.MP.Entities.Messages
{
    public abstract class MessageHandler : IMessageHandler
    {
        private readonly XDocument requestXml;
        protected readonly RequestMessageBase requestMessage;

        protected MessageHandler(Stream inputStream)
            : this(XDocument.Load(inputStream)) {}

        protected MessageHandler(XDocument requestXml) {
            this.requestXml = requestXml;
            this.requestMessage = RequestMessageBase.Create(this.requestXml);
        }

        public bool CancelExecute { get; set; }

        //public RequestMessageBase RequestMessage {
        //    get { return requestMessage; }
        //}

        #region Implementation of IMessageHandler

        public ResponseMessageImage CreateImageResponse(string mediaId) {
            var response = new ResponseMessageImage(mediaId);
            response.SetMessageBase(requestMessage);
            return response;
        }

        public ResponseMessageMusic CreateMusicResponse(string thumbMediaId) {
            var response = new ResponseMessageMusic(thumbMediaId);
            response.SetMessageBase(requestMessage);
            return response;
        }

        public ResponseMessageNews CreateNewsResponse(Article article) {
            var response = new ResponseMessageNews();
            response.Add(article);
            response.SetMessageBase(requestMessage);
            return response;
        }

        public ResponseMessageNews CreateNewsResponse(IEnumerable<Article> articles) {
            var response = new ResponseMessageNews();
            response.AddRange(articles);
            response.SetMessageBase(requestMessage);
            return response;
        }

        public ResponseMessageText CreateTextResponse(string content) {
            var response = new ResponseMessageText(content);
            response.SetMessageBase(requestMessage);
            return response;
        }

        public ResponseMessageVideo CreateVideoResponse(string mediaId) {
            var response = new ResponseMessageVideo(mediaId);
            response.SetMessageBase(requestMessage);
            return response;
        }

        public ResponseMessageVoice CreateVoiceResponse(string mediaId) {
            var response = new ResponseMessageVoice(mediaId);
            response.SetMessageBase(requestMessage);
            return response;
        }

        #endregion

        public void Execute() {
            OnExecuting();

            OnExecuted();
        }

        protected abstract ResponseMessageBase DefaultResponseMessage();

        protected virtual void OnExecuting() { }

        protected virtual void OnExecuted() { }
    }
}
